package com.ustc.hewei.nettyrpc2_0.common.config;

import com.ustc.hewei.nettyrpc2_0.common.mock.MultiMock;
import com.ustc.hewei.nettyrpc2_0.common.utils.Constants;
import com.ustc.hewei.nettyrpc2_0.common.utils.PropertiesUtil;
import com.ustc.hewei.nettyrpc2_0.common.warp.ZkNode;
import com.ustc.hewei.nettyrpc2_0.netty.client.ClientProxy;
import com.ustc.hewei.nettyrpc2_0.netty.client.loadBalance.CommonLoadBalance;
import com.ustc.hewei.nettyrpc2_0.netty.client.loadBalance.impl.ConsistentHash;
import com.ustc.hewei.nettyrpc2_0.netty.client.loadBalance.impl.RandomWithWeight;
import com.ustc.hewei.nettyrpc2_0.netty.client.loadBalance.impl.RoundRobin;
import com.ustc.hewei.nettyrpc2_0.netty.client.manager.HandlerManager;
import com.ustc.hewei.nettyrpc2_0.netty.server.handler.RequestHandler;
import com.ustc.hewei.nettyrpc2_0.netty.server.net.NettyServer;
import com.ustc.hewei.nettyrpc2_0.netty.server.net.RpcServer;
import com.ustc.hewei.nettyrpc2_0.zookeeper.register.ServiceRegister;
import com.ustc.hewei.nettyrpc2_0.zookeeper.register.ZkServiceRegister;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @description: 配置类
* @author hewei
* @date 2022/9/5 21:04
* @version 1.0
*/

@Configuration
public class AutoConfiguration {

    @Bean
    public HandlerManager handlerManager(@Autowired CommonLoadBalance loadBalance) {
        return new HandlerManager(loadBalance);
    }

    @Bean
    public CommonLoadBalance loadBalance() {
        switch (PropertiesUtil.getString(Constants.serializerType)) {
            case "CONSISTENT_HASH":
                return new ConsistentHash();
            case "RANDOM":
                return new RandomWithWeight();
            case "ROUND_ROBIN":
                return new RoundRobin();
            default:
                return new ConsistentHash();
        }
    }

    @Bean
    @ConfigurationProperties(prefix = "rpc")
    public RpcProperties properties() {
        return new RpcProperties();
    }

    @Bean
    public ClientProxy clientProxy(@Autowired HandlerManager handlerManager,
                                   @Autowired MultiMock multiMock) {
        return new ClientProxy(handlerManager, multiMock);
    }

    @Bean
    public ServiceRegister zkServiceRegister(@Autowired ServiceDiscovery<ZkNode> serviceDiscovery) {
        return new ZkServiceRegister(PropertiesUtil.getInt(Constants.port), serviceDiscovery);
    }

    @Bean
    public DefaultRpcProcessor defaultRpcProcessor(@Autowired ServiceRegister serviceRegister,
                                                   @Autowired ClientProxy clientProxy,
                                                   @Autowired RpcServer rpcServer,
                                                   @Autowired ServiceDiscovery<ZkNode> serviceDiscovery,
                                                   @Autowired HandlerManager handlerManager) {
        return new DefaultRpcProcessor(serviceRegister, rpcServer, clientProxy, serviceDiscovery, handlerManager);
    }

    @Bean
    public RequestHandler requestHandler(@Autowired ServiceRegister serviceRegister) {
        return new RequestHandler(serviceRegister);
    }

    @Bean
    public RpcServer rpcServer(@Autowired RequestHandler requestHandler,
                               @Autowired ServiceRegister serviceRegister) {
        return new NettyServer(PropertiesUtil.getInt(Constants.port), requestHandler, serviceRegister);
    }

//    @Bean
//    public Test1 test1(@Autowired ClientProxy clientProxy) {
//        return clientProxy.getProxy(Test1.class);
//    }

    @Bean
    public MultiMock multiMock() {
        return new MultiMock();
    }

    @Bean
    public ServiceAutowireConfig serviceAutowireConfig(@Autowired ClientProxy clientProxy,
                                                       @Autowired HandlerManager handlerManager,
                                                       @Autowired ServiceDiscovery<ZkNode> serviceDiscovery) {
        return new ServiceAutowireConfig(clientProxy, serviceDiscovery, handlerManager);
    }
}
